package queue;

public class ArrayQueue implements IQueue {
	private int gf;
	private int i;
	private int f;
	private int n;
	private Object[] array;

	public ArrayQueue() {
		super();
		this.gf = 0;
		this.i = 0;
		this.f = 0;
		this.n = 2;
		this.array = new Object[n];
	}

	public ArrayQueue(int gf) {
		super();
		this.gf = (gf < 0) ? (-1 * gf) : gf;
		this.i = 0;
		this.f = 0;
		this.n = 2;
		this.array = new Object[n];
	}

	@Override
	public void enqueue(Object o) {
		if (this.size() == n - 1) {
			Object[] temp;
			if (gf == 0) {
				n *= n;
				temp = new Object[n];
			} else {
				n *= gf;
				temp = new Object[n];
			}
			for (int k = 0; k < array.length; k++) {
				temp[k] = array[k];
			}
			array = temp;
		}
		array[f] = o;
		f = (f + 1) % n;
	}

	@Override
	public Object dequeue() throws EmptyQueueExeption {
		if (this.isEmpty()) {
			throw new EmptyQueueExeption(null);
		}
		Object o = array[i];
		array[i] = null;
		i = (i + 1) % n;
		return o;
	}

	@Override
	public Object front() throws EmptyQueueExeption {
		if (this.isEmpty()) {
			throw new EmptyQueueExeption(null);
		}
		return array[i];
	}

	@Override
	public int size() {
		return (n - i + f) % n;
	}

	@Override
	public boolean isEmpty() {
		return i == f;
	}
	
	@Override
	public String toString() {
		String out = "ArrayQueue:\n";
//		for(int k = i; k == f; k = (k + 1) % n) {
		for (int k = 0; k < array.length; k++) {
			out += "\t" +
					((array[k] != null) ?
							array[k].toString() : "vazio") +
					((k == i) ? " >" : "" ) +
					((k == f) ? " <" : "" ) +
					"\n";
		}
		return out;
	}
	
	public String elementsToString() {
		String out = "ArrayQueue:\n";
		for(int k = i; k == f; k = (k + 1) % n) {
			out += "\t" +
					array[k].toString() +
					"\n";
		}
		return out;
	}
}
